<?php

class SJB_InvoiceManager extends SJB_ObjectManager
{
	public static function saveInvoice($invoice)
	{
		$serializedItemsDetails['items'] = $invoice->getPropertyValue('items');
		$products = isset($serializedItemsDetails['items']['products']) ? $serializedItemsDetails['items']['products'] : array();
		$products = implode(',', $products);
		$invoice->addProperty(
			array ( 'id'		=> 'serialized_items_info',
					'type'		=> 'text',
					'value'		=> serialize($serializedItemsDetails),
					'is_system' => true,
			)
		);
		$invoice->addProperty(
				array ( 'id'		=> 'product_sid',
						'type'		=> 'string',
						'value'		=> $products,
						'is_system' => true,
				)
		);
		$invoice->deleteProperty('items');

		$serializedTaxDetails['tax_info'] = $invoice->getPropertyValue('tax_info');
		$invoice->addProperty(
			array ( 'id'		=> 'serialized_tax_info',
					'type'		=> 'text',
					'value'		=> serialize($serializedTaxDetails),
					'is_system' => true,
			)
		);
		$invoice->deleteProperty('tax_info');

		$user_sid = $invoice->getPropertyValue('user_sid');
		$user_info = SJB_UserManager::getUserInfoBySID($user_sid);
		if (!empty($user_info['parent_sid'])) {
			$invoice->setPropertyValue('subuser_sid', $user_sid);
			$invoice->setPropertyValue('user_sid', $user_info['parent_sid']);
		}

		$dateProperty = $invoice->getProperty('date');
		$value = $dateProperty->getValue();
		if (!$dateProperty->type->getConvertToDBDate() && $value != null) {
			$invoice->setPropertyValue('date', SJB_I18N::getInstance()->getDate($value));
		}

		$invoice->setPropertyValue('sub_total', SJB_I18N::getInstance()->getFloat($invoice->getPropertyValue('sub_total')));
		$invoice->setPropertyValue('total', SJB_I18N::getInstance()->getFloat($invoice->getPropertyValue('total')));
		parent::saveObject('invoices', $invoice);

		if ($value == null) {
			SJB_DB::query('UPDATE `invoices` SET `date`= NOW() WHERE `sid`=?n',$invoice->getSID());
		}
	}

	public static function getInvoiceInfoBySID($invoiceSID)
	{
		$invoice_info = parent::getObjectInfoBySID('invoices', $invoiceSID);
		if (!empty($invoice_info['serialized_items_info'])) {
			$serialized_items_info = unserialize($invoice_info['serialized_items_info']);
			$invoice_info = array_merge($invoice_info, $serialized_items_info);
		}
		if (!empty($invoice_info['serialized_tax_info'])) {
			$serialized_tax_info = unserialize($invoice_info['serialized_tax_info']);
			$invoice_info = array_merge($invoice_info, $serialized_tax_info);
		}
		return $invoice_info;
    }

	public static function getObjectBySID($invoiceSID)
	{
    	$invoiceInfo = SJB_InvoiceManager::getInvoiceInfoBySID($invoiceSID);
    	
		if (is_null($invoiceInfo)) {
    		return null;
		}
    	$invoice = new SJB_Invoice($invoiceInfo);
		$invoice->setSID($invoiceSID);
		return $invoice;
	}

	public static function deleteInvoiceBySID($invoiceSID)
	{
		return SJB_InvoiceManager::deleteObject('invoices', $invoiceSID);
	}

	public static function markPaidInvoiceBySID($invoiceSID)
	{
		return SJB_DB::query("UPDATE `invoices` SET `status` = ?s WHERE `sid` = ?n", SJB_Invoice::INVOICE_STATUS_PAID, $invoiceSID);
	}

	public static function markUnPaidInvoiceBySID($invoiceSID)
	{
		return SJB_DB::query("UPDATE `invoices` SET `status` = ?s WHERE `sid` = ?n", SJB_Invoice::INVOICE_STATUS_UNPAID, $invoiceSID);
	}

	public static function getPaymentForms($invoice)
	{
		$activeGateways = SJB_PaymentGatewayManager::getActivePaymentGatewaysList();
		$gatewaysFormInfo = array();
		foreach ($activeGateways as $gatewayInfo) {
			if ($invoice->isRecurring() && empty($gatewayInfo['recurrable'])) {
				continue;
			}
			$gateway = SJB_PaymentGatewayManager::getObjectByID($gatewayInfo['id'], $invoice->isRecurring());
			$gatewaysFormInfo[$gateway->getPropertyValue('id')] = $gateway->buildTransactionForm($invoice);
		}
		return $gatewaysFormInfo;
	}

	public static function generatePDFVersion($html, $invoiceSID)
	{
		ob_end_clean();
		try {
			$pdf = new ExceptionThrowingTCPDF('P', 'mm', 'A4', true, 'UTF-8', false);
			$pdf->SetCreator(PDF_CREATOR);
			$pdf->setPrintHeader(false);
			$pdf->setPrintFooter(false);
			switch (SJB_I18N::getInstance()->getCurrentLanguage()) {
				case 'ja':
					$font = 'cid0jp';
					break;
				case 'zh':
					$font = 'cid0cs';
					break;
				case 'hi':
					$font = 'akshar';
					break;
				case 'fr':
				case 'pt':
					$html = str_replace('à', '&agrave;', $html);
				default:
					$font = 'dejavusans';
			}
			$pdf->SetFont($font, '', 14, '', true);
			$pdf->AddPage();
			$pdf->writeHTML($html, true, false, false, false, '');
			$filename = "invoice" . "_" . $invoiceSID . ".pdf";
			$pdf->Output($filename, 'D');
		} catch (Exception $e) {
			SJB_Error::writeToLog($e->getMessage());
			SJB_HelperFunctions::redirect(SJB_System::getSystemSettings("SITE_URL") . '/edit-invoice/?sid=' . $invoiceSID . '&error=TCPDF_ERROR');
		}
	}

	public static function createInvoiceTemplate($invoiceInfo)
	{
		$items = array();
		foreach ($invoiceInfo['items']['products'] as $key=>$productSID){
			if ($productSID > -1) {
				$product_info = SJB_ProductsManager::getProductInfoBySID($productSID);
				$items[$key]['product'] = $product_info['name'];
				$items[$key]['show_qty'] = $product_info['product_type'] == 'post_listings' && $product_info['pricing_type'] == 'volume_based';
			} else {
				$items[$key]['product'] = $invoiceInfo['items']['custom_item'][$key];
				$items[$key]['show_qty'] = true;
			}
			$items[$key]['qty'] = !empty($invoiceInfo['items']['qty'][$key])?$invoiceInfo['items']['qty'][$key]:'unlimited';
			$items[$key]['amount'] = $invoiceInfo['items']['amount'][$key];
		}
		$invoiceInfo['date'] = SJB_I18N::getInstance()->getDate($invoiceInfo['date']);
		$invoiceInfo['items'] = $items;

		if ($invoiceInfo['include_tax']) {
			$invoiceInfo['tax_amount'] = $invoiceInfo['tax_info']['tax_amount'];
			$invoiceInfo['tax_name']   = $invoiceInfo['tax_info']['tax_name'];
			$invoiceInfo['taxSid']     = $invoiceInfo['tax_info']['sid'];
		} else {
			$invoiceInfo['taxSid'] = false;
		}

		return $invoiceInfo;
	}

	public static function getExistingInvoiceSID($userSID, $itemsInfo, $taxInfo, $status, $isRecurring)
	{
		return SJB_DB::queryValue('select `sid` from `invoices` where `status` = ?s  and `user_sid` = ?n and `serialized_items_info` = ?s and `serialized_tax_info` = ?s and `is_recurring` = ?n',
			$status, $userSID, serialize($itemsInfo), serialize($taxInfo), $isRecurring);
	}

	public static function getTotalPrice($subTotal, $taxAmount, $priceIncludesTax)
	{
		if ($priceIncludesTax) {
			$total = $subTotal;
		} else {
			$total = $subTotal + $taxAmount;
		}
		return $total;
	}

	public static function generateInvoice($invoiceInfo)
	{
		$items_info['items'] = $invoiceInfo['items'];
		$tax_info['tax_info'] = $invoiceInfo['tax_info'];
		$invoice_sid = SJB_InvoiceManager::getExistingInvoiceSID($invoiceInfo['user_sid'], $items_info, $tax_info, SJB_Invoice::INVOICE_STATUS_UNPAID, $invoiceInfo['is_recurring']);
		if (!$invoice_sid) {
			$invoice = new SJB_Invoice($invoiceInfo);
			SJB_InvoiceManager::saveInvoice($invoice);
			$invoice_sid = $invoice->getSID();
			return $invoice_sid;
		}
		return $invoice_sid;
	}

	public static function getInvoicesInfo()
	{
		$res = array();
		$periods = array(
			'Today' => 'YEAR(CURDATE()) = YEAR(i.date) AND DAYOFYEAR(CURDATE()) = DAYOFYEAR(i.date)',
			'This Week' => 'YEARWEEK(CURDATE()) = YEARWEEK(i.date)',
			'This Month' => 'YEAR(CURDATE()) = YEAR(i.date) AND MONTH(CURDATE()) = MONTH(i.date)');

		foreach ($periods as $key => $value) {
			$res[$key]['paid'] = SJB_DB::query("SELECT IFNULL(SUM(i.total), 0) AS `payment` FROM `invoices` i WHERE $value AND `status` = 'Paid'");
			$res[$key]['unpaid'] = SJB_DB::query("SELECT IFNULL(SUM(i.total), 0) AS `payment` FROM `invoices` i WHERE $value AND `status` = 'Unpaid'");
		}
		return $res;
	}

	public static function getTotalInvoices()
	{
		$res = SJB_DB::query("SELECT IFNULL(SUM(i.total), 0) AS `payment` FROM `invoices` i WHERE `status` = 'Paid'");
		if (count($res) == 0) {
			return '0';
		}
		$res = array_shift($res);
		return $res['payment'];
	}

	public static function getTotalUnpaidInvoices()
	{
		$res = SJB_DB::query("SELECT IFNULL(SUM(i.total), 0) AS `payment` FROM `invoices` i WHERE `status` = 'Unpaid'");
		if (count($res) == 0) {
			return '0';
		}
		$res = array_shift($res);
		return $res['payment'];
	}
	
	public static function getInvoiceQuantityByProductSID($productSID)
	{
		return SJB_DB::queryValue("SELECT COUNT(*) FROM invoices WHERE FIND_IN_SET(?s, `product_sid`)", $productSID);
	}
}


